import { reqUserLogin, reqUserLogout, reqGetUserInfo } from "@/api/user";
import { staticRoutes, asyncRoutes, anyRoute } from "@/router/routes";
import { cloneDeep } from "lodash";
import router from "@/router";
import { resetRouter } from "@/router";

//用户登录成功后,定义函数从配置的所有异步路由数组中,过滤出用户自己的异步路由
function filterAsyncRoutes(asyncRoutes, routesName) {
  return asyncRoutes.filter((item) => {
    if (routesName.indexOf(item.name) !== -1) {
      // 递归过滤二级路由
      if (item.children && item.children.length) {
        //递归调用,递归过滤完成后给二级路由重新赋值,即为过滤后的二级异步路由
        item.children = filterAsyncRoutes(item.children, routesName);
      }
      return true;
    }
  });
}

// 定义函数,将过滤出来的异步路由和任意路由动态追加到路由器当中
function addRoutes(routes) {
  // debugger;
  // routes.forEach((item) => {
  //   // addRoutes方法每次只能追加一个路由, 封装方法一次性添加数组中的所有路由;
  // });
  router.addRoutes(routes);
}

const state = {
  token: localStorage.getItem("token_key") || "",
  userInfo: {},
};

const mutations = {
  SETTOKEN(state, token) {
    state.token = token;
  },
  USERINFO(state, userInfo) {
    state.userInfo = userInfo;
  },
  RESET_TOKEN(state) {
    state.token = "";
  },
  RESET_USERINFO(state) {
    state.userInfo = {};
  },
};

const actions = {
  //用户登录
  async login({ commit }, loginParams) {
    try {
      let result = await reqUserLogin(loginParams);
      // console.log(result);
      if (result.code === 20000) {
        commit("SETTOKEN", result.data.token);
        localStorage.setItem("token_key", result.data.token);
        return "ok";
      } else {
        alert("登录失败");
      }
    } catch (error) {
      return Promise.reject(new Error("请求登录失败"));
    }
  },

  // 获取用户信息
  async getInfo({ commit }) {
    try {
      let result = await reqGetUserInfo();
      if (result.code === 20000) {
        commit("USERINFO", result.data);
        // 1.拿到用户信息后,调用函数过滤属于用户自己的动态路由数组
        let userAsyncRoutes = filterAsyncRoutes(
          cloneDeep(asyncRoutes),
          result.data.routes
        );
        //2.将过滤出来的异步路由和任意路由动态追加到路由器对象当中
        addRoutes(userAsyncRoutes.concat(anyRoute));

        //3.将遍历生成菜单的路由数组重新赋值,让它是最新的路由器中注册的路由数组,
        //然后菜单就会变成最新的
        router.options.routes = staticRoutes.concat(userAsyncRoutes, anyRoute);
        return "ok";
      } else {
        alert("获取用户信息失败");
      }
    } catch (error) {
      return Promise.reject(new Error("请求获取用户信息失败"));
    }
  },

  //用户退出登录
  async logout({ commit, dispatch }) {
    try {
      await reqUserLogout();
      resetRouter();
      dispatch("resetToken");
      // 重置路由器当中的动态路由
      console.log("退出登录后router中的路由对象是", router.options.routes);
      return "ok";
    } catch (error) {
      return Promise.reject(new Error("退出登录失败"));
    }
  },

  // 重置token
  resetToken({ commit }) {
    commit("RESET_TOKEN");
    commit("RESET_USERINFO");
    localStorage.removeItem("token_key");
  },
};

const getters = {};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters,
};
